﻿using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Nasty.Core.Attributes;
using Nasty.Core.Config;
using Nasty.Core.Entity;
using Nasty.Core.Security;
using SqlSugar;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;

namespace Nasty.Core.SuperExtension
{
    /// <summary>
    /// 专门处理NastyColumn的特性
    /// </summary>
    public static class NastyColumnExtension
    {
        private static readonly string _securityAES = SuperConfig.Get("Security:AES");
        private static HashSet<string> _securityEntities = new HashSet<string>();

        /// <summary>
        /// 判断是不是加密实体
        /// </summary>
        /// <param name="entityInfo"></param>
        /// <returns></returns>
        public static bool IsSecurityEntity(this DataAfterModel entityInfo)
        {
            var fullName = entityInfo.Entity.Type.FullName;

            //快速判断是不是加密实体
            if (_securityEntities.Count != 0) return _securityEntities.Contains(fullName);

            //占位放置没有当前项目没有加密实体，导致重复初始化
            _securityEntities.Add("_Empty");

            var _typeEntities = NastyExtension.Modules.SelectMany((t) => t.GetIBaseEntities());

            foreach (var typeEntity in _typeEntities)
            {
                var isSecurityEntity = typeEntity.GetProperties().Where((t) => IsSecurityColumn(t)).Any();
                if (isSecurityEntity) _securityEntities.Add(typeEntity.FullName);
            }

            return _securityEntities.Contains(fullName);
        }

        public static bool IsSecurityColumn(PropertyInfo info)
        {
            var attribute = info.GetCustomAttribute<NastyColumnAttribute>();
            if (attribute == null) return false;
            return attribute.IsSecurity;
        }

        public static void TryEncrypt(this DataFilterModel entityInfo)
        {
            var column = entityInfo.GetAttribute<NastyColumnAttribute>();
            if (column != null && column.IsSecurity)
            {
                var value = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue).ToString();
                if (string.IsNullOrEmpty(value)) return;

                var encryptValue = AESHelper.Encrypt(value.ToString(), _securityAES);
                entityInfo.EntityColumnInfo.PropertyInfo.SetValue(entityInfo.EntityValue, encryptValue);
            }
        }

        public static void TryDecrypt(this DataAfterModel entityInfo)
        {
            //优化性能,通过预载的加密实体集合快速判断是不是需要解密
            if (!entityInfo.IsSecurityEntity()) return;

            foreach (var column in entityInfo.EntityColumnInfos)
            {
                var attribute = column.PropertyInfo.GetCustomAttribute<NastyColumnAttribute>();
                if (attribute != null && attribute.IsSecurity)
                {
                    try
                    {
                        var value = entityInfo.GetValue(column.PropertyName).ToString();
                        if (string.IsNullOrEmpty(value)) continue;

                        var encryptValue = AESHelper.Decrypt(value, _securityAES);
                        entityInfo.SetValue(column.PropertyName, encryptValue);
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }

        }
    }
}
